home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / data / happysrc / pimain.c < prev    next >
Text File  |  1993-11-30  |  34KB  |  1,220 lines

  1. /************************************************
  2.  **
  3.  **    *** HAPPy P-code Interpriter ***
  4.  **
  5.  **             メイン処理
  6.  **
  7.  **          Copyright (c) H.Asano. 1992,1993.
  8.  ************************************************/
  9.  
  10. #define EXTERN
  11.  
  12. #include <signal.h>
  13. #include <process.h>
  14. #include <io.h>
  15. #include <conio.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include <math.h>
  21. #include <float.h>
  22. #include "version.h"
  23. #include "hapai.h"
  24.  
  25. extern void callsp(void)  ;     /* call standard procedure            */
  26. extern void T_get(fileinfo*, _store*, FILE*,char*); /* 1文字読込      */
  27.  
  28. _store  store[Maxstore] ;       /* 記憶装置                           */
  29.  
  30. _store  *sp        ;            /* スタックポインタ                   */
  31. int pc   ;                      /* program counter                    */
  32. int mp   ;                      /* begginning of a data segment       */
  33. int ep   ;                      /* the maxmum extent of the stack     */
  34. int np   ;                   /* top of the dynamically allocated area */
  35.  
  36. char p   ;                      /* p operand                          */
  37. int  q   ;                      /* q operand                          */
  38.  
  39. boolean readlnflag = true ;     /* 起動時及びinputにreadlnをした時 真 */
  40.  
  41.  
  42. static char *pcofname = "pcode.pco" ; /* P-codeオブジェクトファイル名 */
  43. static char progname[33] ;      /* Pascalプログラム名                 */
  44.  
  45. static int fileno       ;       /* ファイル数                         */
  46. static int     objsize  ;
  47. static FILE    *pcofile ;
  48. static boolean trace    ;       /* 命令トレースフラグ                 */
  49. static boolean infor = false ;  /* -iオプション インタプリタ情報出力       */
  50.  
  51. /******************************************/
  52. /* prerr() : Run-timeエラーメッセージ出力 */
  53. /******************************************/
  54. void prerr(int errno,char *msg)
  55. {
  56.   int i ;
  57.  
  58.      fprintf(stderr,"\n*** [ADDR=%d] HAPPy Run-time error R%03d:\n   --  %s",
  59.                     pc-1,errno,msg) ;
  60.      fprintf(stderr," : 処理打ち切り ***\n");
  61.  
  62.      for(i=0;i<fileno;i++) {            /* ファイルクローズを行う     */
  63.       if((fi[i].mode == generation) &&  /* 生成モードでテキストで     */
  64.          (fi[i].textfile) && (!fi[i].writelnflag)) /* 最後が改行でない*/
  65.         fputc('\n',fi[i].fp) ;          /* 改行を付け加える           */
  66.       fclose(fi[i].fp) ;                /* エラーチェックはしない     */
  67.      }
  68.  
  69.      exit(1) ;                          /* 異常終了                   */
  70. }
  71.  
  72. /****************************************/
  73. /*   cntl_c(): cntl_cが押された時の処理 */
  74. /****************************************/
  75. static void cntl_c(int sig,int subcode)
  76. {
  77.      prerr(152,"<CTRL-C>を受け付けた");
  78. }
  79.  
  80. /****************************************/
  81. /*   real_err(): 浮動小数点例外         */
  82. /****************************************/
  83. static void real_err(int sig, int subcode)
  84. {
  85.   char *type ;
  86.   char buf[80] ;
  87.  
  88.      switch(subcode) {
  89.       case FPE_INVALID        : type = "invalid";             break ;
  90.       case FPE_OVERFLOW       : type = "overflow";            break ;
  91.       case FPE_STACKOVERFLOW  : type = "stack overflow";      break ;
  92.       case FPE_STACKUNDERFLOW : type = "stack underflow";     break ;
  93.      }
  94.      sprintf(buf,"実数演算で異常が起きた(%s)",type) ;
  95.      prerr(150,buf) ;
  96. }
  97.  
  98. /***************************************/
  99. /*   base(id) : 局所的番地を求める     */
  100. /***************************************/
  101. static int base(void)
  102. {
  103.   int ad ;
  104.   int ld ;
  105.  
  106.      if(!p) return(mp) ;                /* ldが0ならmp値を返す        */
  107.      ad = mp ;
  108.      ld = p  ;
  109.      while((ld--))                       /* 0より大きい間繰り返し      */
  110.       ad = store[ad+1].va ;
  111.      return(ad) ;
  112. }
  113.  
  114. /************************ 各P-code の 処理 ****************************/
  115.  
  116. /******************/
  117. /*  ABI           */ /* abolute integers */
  118. /******************/
  119. static void ABI(void)
  120. {
  121.      (*sp).vi = labs((*sp).vi) ;
  122. }
  123.  
  124. /******************/
  125. /*  ABR           */ /* abolute reals */
  126. /******************/
  127. static void ABR(void)
  128. {
  129.      (*sp).vr = (float)fabs((double)(*sp).vr);
  130. }
  131.  
  132. /******************/
  133. /*  ADI           */ /* add integers */
  134. /******************/
  135. static void ADI(void)
  136. {
  137.      sp-- ;
  138.      (*sp).vi += (*(sp+1)).vi ;
  139. }
  140.  
  141. /******************/
  142. /*  ADR           */ /* add reals */
  143. /******************/
  144. static void ADR(void)
  145. {
  146.      sp-- ;
  147.      (*sp).vr += (*(sp+1)).vr ;
  148. }
  149.  
  150. /******************/
  151. /*  AND           */ /* logical and */
  152. /******************/
  153. static void AND(void)
  154. {
  155.  
  156.      sp-- ;
  157.      (*sp).vb = (*sp).vb && (*(sp+1)).vb ;
  158. }
  159.  
  160. /******************/
  161. /*  BAS           */  /* load base mark */
  162. /******************/
  163. static void BAS(void)
  164. {
  165.      (*++sp).va = base() ;
  166. }
  167.  
  168. /******************/
  169. /*  CHR           */  /* convert character */
  170. /******************/
  171. static void CHR(void)
  172. {
  173.     char buf[80] ;
  174.  
  175.      if((0L <= (*sp).vi) && ((*sp).vi <= 255L))
  176.       (*sp).vc = (short)(*sp).vi ;
  177.      else {
  178.       sprintf(buf,"chr: 引数の値(%ld)に対応する文字がない",(*sp).vi);
  179.       prerr(9,buf) ;
  180.      }
  181. }
  182.  
  183. /******************/
  184. /*  CHK           */
  185. /******************/
  186. static void CHK(void)
  187. {
  188.   long i       ;
  189.   long s       ;                        /* 集合                       */
  190.   char buf[80] ;
  191.   static struct {
  192.            int  errno ;
  193.            char *msg  ;
  194.         } errtbl[] = {
  195.     {  1,  "配列の添え字式の値(%ld)が範囲内(%ld~%ld)にない"},
  196.     {  7,  "実値引数の値(%ld)が範囲内(%ld~%ld)にない"},
  197.     {  8,  "実値引数の集合値が範囲内(%ld~%ld)にない"},
  198.     { 17,  "read: バッファ変数の値(%d)が範囲内(%ld~%ld)にない"},
  199.     { 18,  "write: 式の値(%ld)が範囲内(%ld~%ld)にない"},
  200.     { 26,  "pack: 順序型の引数の値(%ld)が範囲内(%ld~%ld)にない"},
  201.     { 29,  "unpack: 順序型の引数の値(%ld)が範囲内(%ld~%ld)にない"},
  202.     { 31,  "unpack: 転送後に詰めなし配列の添え字型を越える"},
  203.     { 49,  "代入文: 右辺値(%ld)が範囲内(%ld~%ld)にない"},
  204.     { 50,  "代入文: 集合値が範囲内(%ld~%ld)にない"},
  205.     { 51,  "case文: 選択式の値(%ld)に合致する選択定数がない"},
  206.     { 52,  "for文: 初期値(%ld)が範囲内(%ld~%ld)にない"},
  207.     { 53,  "for文: 終値(%ld)が範囲内(%ld~%ld)にない"},
  208.     { 71,  "read: 集合型のバッファ変数の値が範囲内(%ld~%ld)にない"},
  209.     { 72,  "write: 集合型の式の値が範囲内(%ld~%ld)にない"},
  210.     {111,  "集合構成子の順序式の値(%ld)がHAPPyの制限範囲内(%ld~%ld)にない"}
  211. } ;
  212.  
  213.      switch(store[pc-1].vo.cdop) {
  214.       case 97 :                         /* chks (集合の範囲チェック)  */
  215.        s = 0 ;
  216.        for(i=store[q-1].vi;i<=store[q].vi;i++)
  217.         addset(s,i);
  218.        s  = (~s & (*sp).vs) ;
  219.        if(s != 0) {
  220.         i = -1;
  221.         while(errtbl[++i].errno != p) ;
  222.         sprintf(buf,errtbl[i].msg,
  223.                    store[q-1].vi,store[q].vi) ;
  224.         prerr(p,buf) ;                  /* エラーメッセージ出力       */
  225.        }
  226.        break ;
  227.  
  228.       default :                         /* chks以外のチェック         */
  229.        if(((*sp).vi < store[q-1].vi) ||
  230.           ((*sp).vi > store[q].vi)) {
  231.        i = -1 ;
  232.        while(errtbl[++i].errno != p) ;
  233.        sprintf(buf,errtbl[i].msg,
  234.                     (*sp).vi, store[q-1].vi,store[q].vi) ;
  235.        prerr(p,buf) ;                   /* エラーメッセージ出力       */
  236.       }
  237.      }
  238. }
  239.  
  240. /******************/
  241. /*  CKA           */  /* Check Address */
  242. /******************/
  243. static void CKA(void)
  244. {
  245.      if((*sp).va == NilValue)
  246.       prerr(3,"対象変数のポインタ変数の値がnilである") ;
  247.  
  248.      if(!((np <= (*sp).va) && ((*sp).va < Maxstore)))
  249.       prerr(4,"対象変数のポインタ変数の値が不定である") ;
  250. }
  251.  
  252. /******************/
  253. /*  CSP           */  /* call standard procedure */
  254. /******************/
  255. static void CSP(void)
  256. {
  257.      callsp() ;
  258. }
  259.  
  260. /******************/
  261. /*  CUI           */ /* Call User procedure Indirect */
  262. /******************/
  263. static void CUI(void)
  264. {
  265.   int calladr ;
  266.  
  267.      calladr = (*sp--).va ;             /* 実行開始アドレス取得       */
  268.      mp=(sp-store)-(p+4)  ;             /* 4はmstと関係               */
  269.      store[mp+4].va = pc       ;        /* 戻り番地                   */
  270.      pc = calladr              ;        /* jump                       */
  271. }
  272.  
  273. /******************/
  274. /*  CUP           */ /* Call User Procedure */
  275. /******************/
  276. static void CUP(void)
  277. {
  278.      mp=(sp-store)-(p+4) ;              /* 4はmstと関係*/
  279.      store[mp+4].va = pc      ;         /* 戻り番地    */
  280.      pc = q                   ;         /* jump        */
  281. }
  282.  
  283. /******************/
  284. /*  DEC           */
  285. /******************/
  286. static void DEC(void)
  287. {
  288.      switch(p) {
  289.       case 1 : (*sp).vi -= q ;
  290.                return ;
  291.       case 6 : (*sp).vc -= q ;
  292.                return ;
  293.       case 3 : (*sp).vb -= q ;
  294.                return ;
  295.       case 0 : (*sp).va -= q ;
  296.                return ;
  297.       case 2 : (*sp).vr -= (float)q ;
  298.                return ;
  299.      }
  300. }
  301.  
  302. /******************/
  303. /*  DIF           */
  304. /******************/
  305. static void DIF(void)
  306. {
  307.      sp--;
  308.      (*sp).vs  &= ((*sp).vs ^ (*(sp+1)).vs) ;
  309. }
  310.  
  311. /******************/
  312. /*  DVI           */
  313. /******************/
  314. static void DVI(void)
  315. {
  316.      if((*sp--).vi == 0) prerr(45,"div演算子: 0で割ろうとしている") ;
  317.      (*sp).vi /= (*(sp+1)).vi ;
  318. }
  319.  
  320. /******************/
  321. /*  DVR           */
  322. /******************/
  323. static void DVR(void)
  324. {
  325.      if((*sp--).vr == (float)0.0)
  326.       prerr(44,"/演算子: 0で割ろうとしている") ;
  327.      (*sp).vr /= (*(sp+1)).vr ;
  328. }
  329.  
  330. /******************/
  331. /*  EJP           */  /* Extra block Jump */
  332. /******************/
  333. static void EJP(void)
  334. {
  335.   int req ;
  336.  
  337.      req = base() ;
  338.      while(mp != req) {                 /* スタックの枠を解放         */
  339.       sp = store + mp-1;
  340.       ep = store[mp+3].va;
  341.       mp = store[mp+2].va;
  342.      }
  343.      pc = q;
  344. }
  345.  
  346. /******************/
  347. /*  ENT           */
  348. /******************/
  349. static void ENT(void)
  350. {
  351.      if(p==1) {                         /* p=1                        */
  352.       if(q <= np-mp)                    /* mp+q <= np の時            */
  353.        sp = store + mp + q ;
  354.       else prerr(122,"スタック用のメモリが不足している") ;
  355.      }
  356.      else {                             /* p=2                        */
  357.       if( q <= np-(sp-store))           /* sp+q <= ep の時            */
  358.        ep = (sp-store)+q ;              /* スタックの枠定義           */
  359.       else prerr(122,"スタック用のメモリが不足している") ;
  360.      }
  361. }
  362.  
  363. /******************/
  364. /*  EQU           */
  365. /******************/
  366. static void EQU(void)
  367. {
  368.  
  369.      sp-- ;
  370.  
  371.      switch(p) {
  372.       case 1: (*sp).vb = (*sp).vi == (*(sp+1)).vi ;
  373.               return;
  374.       case 0: (*sp).vb = (*sp).va == (*(sp+1)).va ;
  375.               return;
  376.       case 6: (*sp).vb = (*sp).vc == (*(sp+1)).vc ;
  377.               return;
  378.       case 2: (*sp).vb = (*sp).vr == (*(sp+1)).vr ;
  379.               return;
  380.       case 3: (*sp).vb = (*sp).vb == (*(sp+1)).vb ;
  381.               return;
  382.       case 4: (*sp).vb = (*sp).vs == (*(sp+1)).vs ;
  383.               return;
  384.       case 5: (*sp).vb = (memcmp(&(store[(*sp).va].vc),
  385.                                &(store[(*(sp+1)).va].vc),
  386.                                q*sizeof(_store)) == 0);
  387.      }
  388. }
  389.  
  390. /******************/
  391. /*  FJP           */
  392. /******************/
  393. static void FJP(void)
  394. {
  395.      if(! (*(sp--)).vb) pc = q;
  396. }
  397.  
  398. /******************/
  399. /*  FLO           */
  400. /******************/
  401. static void FLO(void)
  402. {
  403.      (*(sp-1)).vr = (float)(*(sp-1)).vi ;
  404. }
  405.  
  406. /******************/
  407. /*  FLT           */
  408. /******************/
  409. static void FLT(void)
  410. {
  411.      (*sp).vr = (float)(*sp).vi ;
  412. }
  413.  
  414. /******************/
  415. /*  GEQ           */
  416. /******************/
  417. static void GEQ(void)
  418. {
  419.      sp-- ;
  420.      switch(p) {
  421.       case 1: (*sp).vb = (*sp).vi >= (*(sp+1)).vi ;
  422.               return;
  423.       case 6: (*sp).vb = (*sp).vc >= (*(sp+1)).vc ;
  424.               return;
  425.       case 2: (*sp).vb = (*sp).vr >= (*(sp+1)).vr ;
  426.               return;
  427.       case 3: (*sp).vb = (*sp).vb >= (*(sp+1)).vb ;
  428.               return;
  429.       case 4: (*sp).vb =
  430.               ((*(sp+1)).vs & ((*(sp+1)).vs ^ (*sp).vs))
  431.                                 ? false : true ;
  432.               return;
  433.       case 5: (*sp).vb = (memcmp(&(store[(*sp).va].vc),
  434.                                      &(store[(*(sp+1)).va].vc),
  435.                                      q*sizeof(_store)) >= 0);
  436.      }
  437. }
  438.  
  439. /******************/
  440. /*  GRT           */
  441. /******************/
  442. static void GRT(void)
  443. {
  444.      sp-- ;
  445.      switch(p) {
  446.       case 1: (*sp).vb = (*sp).vi > (*(sp+1)).vi ;
  447.               return;
  448.       case 6: (*sp).vb = (*sp).vc > (*(sp+1)).vc ;
  449.               return;
  450.       case 2: (*sp).vb = (*sp).vr > (*(sp+1)).vr ;
  451.               return;
  452.       case 3: (*sp).vb = (*sp).vb > (*(sp+1)).vb ;
  453.               return;
  454.       case 5: (*sp).vb = (memcmp(&(store[(*sp).va].vc),
  455.                                      &(store[(*(sp+1)).va].vc),
  456.                                      q*sizeof(_store)) > 0);
  457.      }
  458. }
  459.  
  460. /******************/
  461. /*  INC           */
  462. /******************/
  463. static void INC(void)
  464. {
  465.      switch(p) {
  466.       case 1 : (*sp).vi += q ;
  467.                return ;
  468.       case 6 : (*sp).vc += q ;
  469.                return ;
  470.       case 3 : (*sp).vb += q ;
  471.                return ;
  472.       case 0 : (*sp).va += q ;
  473.                return ;
  474.       case 2 : (*sp).vr += (float)q ;
  475.                return ;
  476.      }
  477. }
  478.  
  479. /******************/
  480. /*  IND           */
  481. /******************/
  482. static void IND(void)
  483. {
  484.      (*sp)=store[(*sp).va+q] ;
  485. }
  486.  
  487. /******************/
  488. /*  INN           */
  489. /******************/
  490. static void INN(void)
  491. {
  492.   integer i;
  493.  
  494.      i=(*(--sp)).vi ;
  495.      (*sp).vb = (boolean)inset((*(sp+1)).vs,i) ;
  496. }
  497.  
  498. /******************/
  499. /*  INT           */
  500. /******************/
  501. static void INT(void)
  502. {
  503.      sp--;
  504.      (*sp).vs &= (*(sp+1)).vs  ;
  505. }
  506.  
  507. /******************/
  508. /*  IOR           */ /* logical inclusive or */
  509. /******************/
  510. static void IOR(void)
  511. {
  512.      sp-- ;
  513.      (*sp).vb = (*sp).vb || (*(sp+1)).vb ;
  514. }
  515.  
  516. /******************/
  517. /*  IXA           */
  518. /******************/
  519. static void IXA(void)
  520. {
  521.      (*sp).vi -= store[q-1].vi ;       /* 下限値を引く               */
  522.      (*sp).va += (int)store[q].vi*(int)(*(sp--)).vi ;
  523. }
  524.  
  525. /******************/
  526. /*  LAO           */  /* load base-level address */
  527. /******************/
  528. static void LAO(void)
  529. {
  530.      (*(++sp)).va = q ;
  531. }
  532.  
  533. /******************/
  534. /*  LAP           */  /* Load Address Procedure */
  535. /******************/
  536. static void LAP(void)
  537. {
  538.      (*(++sp)).va = q ;
  539. }
  540.  
  541. /******************/
  542. /*  LCA           */
  543. /******************/
  544. static void LCA(void)
  545. {
  546.      (*(++sp)).va = q ;
  547. }
  548.  
  549. /******************/
  550. /*  LCI           */  /* load constant integer */
  551. /******************/
  552. static void LCI(void)
  553. {
  554.      (*(++sp)).vi = store[q].vi ;
  555. }
  556.  
  557. /******************/
  558. /*  LDA           */  /* load level p address */
  559. /******************/
  560. static void LDA(void)
  561. {
  562.      (*(++sp)).va = base()+q ;
  563. }
  564.  
  565. /******************/
  566. /*  LDC           */  /* load constant */
  567. /******************/
  568. static void LDC(void)
  569. {
  570.      sp++ ;
  571.      switch(p) {
  572.       case 1 : (*sp).vi = q;           /* integer */
  573.                return ;
  574.       case 6 : (*sp).vc = q;           /* char    */
  575.                return ;
  576.       case 3 : (*sp).vb = q;           /* boolean */
  577.                return ;
  578.       case 2 : (*sp).vr = store[q].vr; /* real    */
  579.                return ;
  580.       case 4 : (*sp).vs = store[q].vs ;/* set     */
  581.                return ;
  582.       case 0 : (*sp).va = NilValue ;   /* nil     */
  583.                     /* programmer が 生成できない値   */
  584.      }
  585. }
  586.  
  587. /******************/
  588. /*  LDO           */  /* load contents of base-level address */
  589. /******************/
  590. static void LDO(void)
  591. {
  592.      (*(++sp))=store[q] ;
  593. }
  594.  
  595. /******************/
  596. /*  LDOC          */  /* load char of base-level address */
  597. /******************/
  598.      /* inputバッファの値が決まっていない時のために
  599.         特別な処理が必要なので、この処理を作りました */
  600. static void LDOC(void)
  601. {
  602.      if((q == fi[0].fileadr) && readlnflag) {
  603.       T_get(fi,store+fi[0].fileadr,stdin,"get");
  604.       readlnflag = false ;
  605.      }
  606.  
  607.      *(++sp) = store[q] ;
  608. }
  609.  
  610. /******************/
  611. /*  LEQ           */
  612. /******************/
  613. static void LEQ(void)
  614. {
  615.      sp-- ;
  616.      switch(p) {
  617.       case 1: (*sp).vb = (*sp).vi <= (*(sp+1)).vi ;
  618.               return;
  619.       case 6: (*sp).vb = (*sp).vc <= (*(sp+1)).vc ;
  620.               return;
  621.       case 2: (*sp).vb = (*sp).vr <= (*(sp+1)).vr ;
  622.               return;
  623.       case 3: (*sp).vb = (*sp).vb <= (*(sp+1)).vb ;
  624.               return;
  625.       case 4: (*sp).vb =
  626.               ((*sp).vs & ((*sp).vs ^ (*(sp+1)).vs))
  627.                             ? false : true ;
  628.               return;
  629.       case 5: (*sp).vb = (memcmp(&(store[(*sp).va].vc),
  630.                                      &(store[(*(sp+1)).va].vc),
  631.                                      q*sizeof(_store)) <= 0);
  632.      }
  633. }
  634.  
  635. /******************/
  636. /*  LES           */
  637. /******************/
  638. static void LES(void)
  639. {
  640.      sp-- ;
  641.      switch(p) {
  642.       case 1: (*sp).vb = (*sp).vi < (*(sp+1)).vi ;
  643.               return;
  644.       case 6: (*sp).vb = (*sp).vc < (*(sp+1)).vc ;
  645.               return;
  646.       case 2: (*sp).vb = (*sp).vr < (*(sp+1)).vr ;
  647.               return;
  648.       case 3: (*sp).vb = (*sp).vb < (*(sp+1)).vb ;
  649.               return;
  650.       case 5: (*sp).vb = (memcmp(&(store[(*sp).va].vc),
  651.                                      &(store[(*(sp+1)).va].vc),
  652.                                      q*sizeof(_store)) < 0);
  653.      }
  654. }
  655.  
  656. /******************/
  657. /*  LOD           */  /* load contents of address at level p */
  658. /******************/
  659. static void LOD(void)
  660. {
  661.  
  662.      *(++sp)=store[base()+q];
  663. }
  664.  
  665. /******************/
  666. /*  MMS           */  /* Make Multiple Set */
  667. /******************/
  668. static void MMS(void)
  669. {
  670.   long    s = 0;
  671.   integer i ;
  672.  
  673.      sp--    ;
  674.      for(i=(*sp).vi;i<=(*(sp+1)).vi;i++)
  675.       addset(s,i);
  676.      (*sp).vs = s;
  677. }
  678.  
  679. /******************/
  680. /*  MOD           */
  681. /******************/
  682. static void MOD(void)
  683. {
  684.      if((*sp--).vi <= 0)
  685.       prerr(46,"mod演算子: 右辺値が0または負である") ;
  686.      (*sp).vi %= (*(sp+1)).vi ;
  687. }
  688.  
  689. /******************/
  690. /*  MOV           */
  691. /******************/
  692. static void MOV(void)
  693. {
  694.      if(p==1)
  695.       memcpy(&store[(*(sp-1)).va],
  696.              &store[(*sp).va],  q*sizeof(_store)) ;
  697.      else                               /* pack,unpackの時使う        */
  698.       memcpy(&store[(*sp).va],
  699.              &store[(*(sp-1)).va],  q*sizeof(_store)) ;
  700.  
  701.      sp-=2 ;
  702.  
  703. }
  704.  
  705. /******************/
  706. /*  MPI           */
  707. /******************/
  708. static void MPI(void)
  709. {
  710.      sp--;
  711.      (*sp).vi *= (*(sp+1)).vi ;
  712. }
  713.  
  714. /******************/
  715. /*  MPR           */
  716. /******************/
  717. static void MPR(void)
  718. {
  719.      sp--;
  720.      (*sp).vr *= (*(sp+1)).vr ;
  721. }
  722.  
  723. /******************/
  724. /*  MSI           */ /* Mark Stack Indirect */
  725. /******************/
  726. static void MSI(void)
  727. {
  728.      (*(sp+2)).va = (unsigned char)(*(sp--)).va ;     /* 静鎖    */
  729.      (*(sp+3)).va = mp  ;                             /* 動鎖    */
  730.      (*(sp+4)).va = ep  ;                             /* 旧ep    */
  731.      sp += 5            ;
  732. }
  733.  
  734. /******************/
  735. /*  MST           */ /* Mark STack */
  736. /******************/
  737. static void MST(void)
  738. {
  739.      (*(sp+2)).va = base()  ;      /* 静鎖 */
  740.      (*(sp+3)).va = mp      ;      /* 動鎖 */
  741.      (*(sp+4)).va = ep      ;      /* 旧ep */
  742.      sp += 5                ;
  743. }
  744.  
  745. /******************/
  746. /*  NEQ           */
  747. /******************/
  748. static void NEQ(void)
  749. {
  750.      sp-- ;
  751.      switch(p) {
  752.       case 1: (*sp).vb = (*sp).vi != (*(sp+1)).vi ;
  753.               return;
  754.       case 0: (*sp).vb = (*sp).va != (*(sp+1)).va ;
  755.               return;
  756.       case 6: (*sp).vb = (*sp).vc != (*(sp+1)).vc ;
  757.               return;
  758.       case 2: (*sp).vb = (*sp).vr != (*(sp+1)).vr ;
  759.               return;
  760.       case 3: (*sp).vb = (*sp).vb != (*(sp+1)).vb ;
  761.               return;
  762.       case 4: (*sp).vb = (*sp).vs != (*(sp+1)).vs ;
  763.                return;
  764.       case 5: (*sp).vb = (memcmp(&(store[(*sp).va].vc),
  765.                                      &(store[(*(sp+1)).va].vc),
  766.                                      q*sizeof(_store)) != 0);
  767.      }
  768. }
  769.  
  770. /******************/
  771. /*  NGI           */
  772. /******************/
  773. static void NGI(void)
  774. {
  775.      (*sp).vi = - (*sp).vi ;
  776. }
  777.  
  778. /******************/
  779. /*  NGR           */
  780. /******************/
  781. static void NGR(void)
  782. {
  783.      (*sp).vr = - (*sp).vr ;
  784. }
  785.  
  786. /******************/
  787. /*  NOP           */  /* no operation */  /* 現在使われていません */
  788. /******************/
  789. static void NOP(void)
  790. {
  791. }
  792.  
  793. /******************/
  794. /*  NOT           */
  795. /******************/
  796. static void NOT(void)
  797. {
  798.      (*sp).vb = ! (*sp).vb ;
  799. }
  800.  
  801. /******************/
  802. /*  ODD           */
  803. /******************/
  804. static void ODD(void)
  805. {
  806.      (*sp).vb = (((*sp).vi % 2) != 0) ;
  807. }
  808.  
  809. /******************/
  810. /*  ORD           */  /* ORdinary */
  811. /******************/
  812. static void ORD(void)
  813. {
  814.      if(p == 3)                        /* ordb                        */
  815.       (*sp).vi = (integer)(*sp).vb ;
  816.      else                              /* ordc                        */
  817.       (*sp).vi = (integer)(*sp).vc ;
  818. }
  819.  
  820. /******************/
  821. /*  RET           */
  822. /******************/
  823. static void RET(void)
  824. {
  825.      if(p==0) sp = store + mp -1 ;      /* retp:p=0  p<>0は以下の命令 */
  826.      else     sp = store + mp    ;      /* reti,retr,retc,retb,rets   */
  827.      pc  = store[mp+4].va ;             /* pc 復帰                    */
  828.      ep  = store[mp+3].va ;             /* ep 復帰                    */
  829.      mp  = store[mp+2].va ;             /* mp 復帰                    */
  830. }
  831.  
  832. /******************/
  833. /*  ROU           */  /* round */
  834. /******************/
  835. static void ROU(void)
  836. {
  837.      (*sp).vi = (integer)floor((double)((*sp).vr + 0.5)) ;
  838. }
  839.  
  840. /******************/
  841. /*  SBI           */ /* subtruct integers */
  842. /******************/
  843. static void SBI(void)
  844. {
  845.      sp-- ;
  846.      (*sp).vi -= (*(sp+1)).vi ;
  847. }
  848.  
  849. /******************/
  850. /*  SBR           */ /* subtruct reals */
  851. /******************/
  852. static void SBR(void)
  853. {
  854.      sp-- ;
  855.      (*sp).vr -= (*(sp+1)).vr ;
  856. }
  857.  
  858. /******************/
  859. /*  SGS           */
  860. /******************/
  861. static void SGS(void)
  862. {
  863.   long s = 0;
  864.  
  865.      addset(s,(*sp).vi);
  866.      (*sp).vs = s;
  867. }
  868.  
  869. /******************/
  870. /*  SQI           */
  871. /******************/
  872. static void SQI(void)
  873. {
  874.      (*sp).vi *= (*sp).vi ;
  875. }
  876.  
  877. /******************/
  878. /*  SQR           */
  879. /******************/
  880. static void SQR(void)
  881. {
  882.      (*sp).vr *= (*sp).vr ;
  883. }
  884.  
  885. /******************/
  886. /*  SRO           */  /* store at base-level address */
  887. /******************/
  888. static void SRO(void)
  889. {
  890.      store[q] = *(sp--) ;
  891. }
  892.  
  893. /******************/
  894. /*  STO           */
  895. /******************/
  896. static void STO(void)
  897. {
  898.      store[(*(sp-1)).va] = *sp ;
  899.      sp-=2 ;
  900. }
  901.  
  902. /******************/
  903. /*  STP           */  /* stop */
  904. /******************/
  905. static void STP(void)
  906. {
  907.   int i ;
  908.  
  909.      for(i=0;i<fileno;i++) {            /* ファイルクローズを行う     */
  910.       if((fi[i].mode == generation) &&  /* 生成モードでテキストで     */
  911.          (fi[i].textfile) && (!fi[i].writelnflag)) /* 最後が改行でない*/
  912.         fputc('\n',fi[i].fp) ;          /* 改行を付け加える           */
  913.       fclose(fi[i].fp) ;                /* エラーチェックはしない     */
  914.      }
  915.      exit(0) ;
  916. }
  917.  
  918. /******************/
  919. /*  STR           */  /* store contents at address at level p */
  920. /******************/
  921. static void STR(void)
  922. {
  923.      store[base()+q] = *sp-- ;
  924. }
  925.  
  926. /******************/
  927. /*  TRA           */  /* trace of execuction */
  928. /******************/
  929. static void TRA(void)
  930. {
  931.      trace = (p==1) ;                   /* tra 1 の時 トレースON      */
  932. }
  933.  
  934. /******************/
  935. /*  TRC           */  /* truncate */
  936. /******************/
  937. static void TRC(void)
  938. {
  939.      (*sp).vi = (integer)(*sp).vr ;
  940. }
  941.  
  942. /******************/
  943. /*  UDF           */  /* UnDeFined instruction */
  944. /******************/
  945. static void UDF(void)
  946. {
  947.      prerr(142,"未定義命令を実行しようとした") ;
  948. }
  949.  
  950. /******************/
  951. /*  UJC           */
  952. /******************/
  953. static void UJC(void)
  954. {
  955.      prerr(51,"case文: 選択式の値に合致する選択定数がない") ;
  956. }
  957.  
  958. /******************/
  959. /*  UJP           */
  960. /******************/
  961. static void UJP(void)
  962. {
  963.      pc = q;
  964. }
  965.  
  966. /******************/
  967. /*  UNI           */
  968. /******************/
  969. static void UNI(void)
  970. {
  971.      sp--   ;
  972.      (*sp).vs |= (*(sp+1)).vs  ;
  973. }
  974.  
  975. /******************/
  976. /*  XJP           */
  977. /******************/
  978. static void XJP(void)
  979. {
  980.      pc = (int)(*sp--).vi+q;
  981. }
  982.  
  983.  
  984. /**********************************************************************/
  985. /*                      P-code   別 処理エントリ表                    */
  986. /**********************************************************************/
  987.  
  988. static struct entry {
  989.        void (*func)(void) ;
  990. } pcd[] = {
  991.            /*         xx0  xx1  xx2  xx3  xx4  xx5  xx6  xx7  xx8  xx9   */
  992.  
  993.            /*00x*/    LOD, LDO, STR, SRO, LDA, LAO, STO, LDC, BAS, IND,
  994.            /*01x*/    INC, MST, CUP, ENT, RET, CSP, IXA, EQU, NEQ, GEQ,
  995.            /*02x*/    GRT, LEQ, LES, UJP, FJP, XJP, CHK, LAP, ADI, ADR,
  996.            /*03x*/    SBI, SBR, SGS, FLT, FLO, TRC, NGI, NGR, SQI, SQR,
  997.            /*04x*/    ABI, ABR, NOT, AND, IOR, DIF, INT, UNI, INN, MOD,
  998.            /*05x*/    ODD, MPI, MPR, DVI, DVR, MOV, LCA, DEC, STP, ORD,
  999.            /*06x*/    CHR, UJC, MMS, MSI, CUI, EJP, LCI, CKA, TRA, ROU,
  1000.            /*07x*/    STR, STR, STR, STR, STR, SRO, SRO, SRO, SRO, SRO,
  1001.            /*08x*/    STO, STO, STO, STO, STO, IND, IND, IND, IND, IND,
  1002.            /*09x*/    UDF, UDF, UDF, UDF, UDF, UDF, CHK, CHK, CHK, CHK,
  1003.            /*10x*/    UDF, UDF, UDF, UDF, UDF, LDO, LDO, LDO, LDO, LDOC,
  1004.            /*11x*/    UDF, UDF, UDF, UDF, UDF, LOD, LOD, LOD, LOD, LOD,
  1005.            /*12x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1006.            /*13x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1007.            /*14x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1008.            /*15x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1009.            /*16x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1010.            /*17x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1011.            /*18x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1012.            /*19x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1013.            /*20x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1014.            /*21x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1015.            /*22x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1016.            /*23x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1017.            /*24x*/    UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
  1018.            /*25x*/    UDF, UDF, UDF, UDF, UDF, UDF
  1019.          };
  1020.  
  1021. /***************************************/
  1022. /* information() : インタプリタ情報出力処理 */
  1023. /***************************************/
  1024. static void information(void)
  1025. {
  1026.    fprintf(stderr,
  1027.     "HAPPy P-code Interpriter Version %s  Copyright (c) H.Asano 1992,1993\n",
  1028.                                       version) ;
  1029.  fputs("\n  HAPPy is the H.Asano Pascal Processing system. (^_^)\n",
  1030.              stderr);
  1031.  fputs(
  1032.   "\n  HAPPyはISO7185規格水準0にほぼ準拠したMS-DOS汎用Pascal処理系です。\n",
  1033.            stderr) ;
  1034.  fputs("  HAPPyの複写・再配付は自由です。\n", stderr) ;
  1035.  
  1036. fputs("\n  piコマンドはpcコマンドで作ったP-codeオブジェクト(pcode.pco)を実行します。\n",
  1037.          stderr);
  1038. }
  1039.  
  1040. /*****************************************/
  1041. /*  inputfilename() : ファイル名入力処理 */
  1042. /*****************************************/
  1043. static void inputfilename(void)
  1044. {
  1045.   int i,j ;
  1046.   int  ch ;
  1047.  
  1048.      fputs("*HAPPy: ファイル( ",stderr) ;
  1049.      for(i=2;i<fileno;i++)  fprintf(stderr,"%s ",fi[i].filename) ;
  1050.      fputs(")の実ファイル名を入力して下さい\n",stderr);
  1051.  
  1052.      for(i=2;i<fileno;i++) {
  1053.       fi[i].textfile = false      ;     /* とりあえずテキストでない   */
  1054.                                         /* としておく                 */
  1055.       fprintf(stderr," %s : ",fi[i].filename) ;
  1056.       while(((ch=getc(stdin)) == ' ') || (ch == '\t'));
  1057.                                         /* 空白,タブの読み飛ばし      */
  1058.       j = 0 ;
  1059.       while(ch != '\n') {
  1060.        fi[i].rfname[j++] = (char)ch ;
  1061.        if(j == MaxRFlen) break ;
  1062.        ch = getc(stdin) ;
  1063.       }  ;
  1064.       fi[i].rfname[j] = '\0' ;
  1065.      }
  1066.  
  1067.      fprintf(stderr,"\n*HAPPy: プログラム(%s)を実行します\n",progname);
  1068. }
  1069.  
  1070. /***************************************/
  1071. /*      init() :  初期設定処理         */
  1072. /***************************************/
  1073. static void init(int argc, char **argv)
  1074. {
  1075.   int i,j ;
  1076.   char ch ;
  1077.   int headerlen       ;                 /* ヘッダ部分の長さ           */
  1078.   char compversion[6] ;                 /* コンパイラバージョン番号   */
  1079.  
  1080.      for(i=2;i<=argc;i++) {             /* オプションの処理           */
  1081.       if(**++argv == '-') {
  1082.        for(j=1;*(*argv+j)!='\0';j++) {
  1083.         switch(tolower(*(*argv+j))) {   /* 大文字の時は小文字に変換   */
  1084.          case 'i' : infor = true   ;    /* information option         */
  1085.                     break          ;
  1086.          case 't' : trace = true   ;    /* trace option               */
  1087.                     break          ;
  1088.         }
  1089.        }
  1090.       }
  1091.      }
  1092.  
  1093.      if(infor) information() ;          /* インタプリタ情報出力            */
  1094.  
  1095.   /**** input,outputファイルのファイル情報を設定する
  1096.           この部分は、暫定的であり、将来変更する予定です ****/
  1097.  
  1098.      strcpy(fi[0].filename,"input")  ;
  1099.      fi[0].fileadr  = 5              ;  /* 5はinputアドレス           */
  1100.      fi[0].filesize = 1              ;
  1101.      strcpy(fi[0].rfname,"標準入力") ;
  1102.      fi[0].fp       = stdin          ;  /* 標準入力                   */
  1103.      fi[0].mode     = inspection     ;  /* 検査モード                 */
  1104.      fi[0].textfile = true           ;  /* テキストファイル           */
  1105.  
  1106.      strcpy(fi[1].filename,"output") ;
  1107.      fi[1].fileadr  = 6              ;  /* 6はoutputアドレス          */
  1108.      fi[1].filesize = 1              ;
  1109.      strcpy(fi[1].rfname,"標準出力") ;
  1110.      fi[1].fp       = stdout         ;  /* 標準出力                   */
  1111.      fi[1].mode     = generation     ;  /* 生成モード                 */
  1112.      fi[1].textfile = true           ;  /* テキストファイル           */
  1113.      fi[1].writelnflag = true        ;
  1114.  
  1115.      fileno = 2 ;
  1116.  
  1117.  
  1118.      pcofile = fopen(pcofname,"rb");
  1119.      if(pcofile==NULL) {
  1120.       fprintf(stderr,
  1121. "I001: P-codeオブジェクトファイル(%s)がない\n",pcofname);
  1122.       exit(2);
  1123.      }
  1124.      objsize = (int)filelength(fileno(pcofile));
  1125.      i = 0 ;
  1126.      do {                               /* バージョン番号を読む       */
  1127.       ch = (char)fgetc(pcofile) ;
  1128.       if(feof(pcofile)) {          /* 途中でファイルが終わってしまった*/
  1129.        fprintf(stderr,
  1130. "I002: P-codeオブジェクトファイル(%s)が不当である",pcofname) ;
  1131.        exit(2) ;
  1132.       }
  1133.      } while((compversion[i++]=ch) != '\0') ;
  1134.      headerlen = i ;
  1135.      if(strcmp(compversion,version)) {
  1136.       fprintf(stderr,
  1137. "I003: コンパイラ(Version %s)とインタプリタ(Version %s)のバージョンが違う\n",
  1138.                     compversion, version) ;
  1139.  
  1140.       exit(2);
  1141.      }
  1142.      i = 0 ;
  1143.      do {                               /* プログラム名を読む         */
  1144.       progname[i] = (char)fgetc(pcofile) ;
  1145.      } while(progname[i++] != '\0') ;
  1146.      headerlen += i ;
  1147.  
  1148.      while((fi[fileno].fileadr = getw(pcofile)) != -1) {
  1149.       headerlen += sizeof(int) ;
  1150.       fi[fileno].filesize = getw(pcofile) ; /* バッファ変数の大きさ   */
  1151.       headerlen += sizeof(int) ;
  1152.       i = 0 ;
  1153.       do {                               /* ファイル名を読む          */
  1154.        fi[fileno].filename[i] = (char)fgetc(pcofile) ;
  1155.       } while(fi[fileno].filename[i++] != '\0') ;
  1156.       fi[fileno].mode = undefined ;     /* ファイルモードは不定       */
  1157.  
  1158.       headerlen += i ;
  1159.       fileno++ ;
  1160.      }
  1161.      if(feof(pcofile)) {                /* コード部分がない場合       */
  1162.       fprintf(stderr,
  1163. "I002: P-codeオブジェクトファイル(%s)が不当である",pcofname) ;
  1164.       exit(2) ;
  1165.      }
  1166.  
  1167.      headerlen += sizeof(int) ;
  1168.      objsize = objsize - headerlen ;
  1169.      fread((char*)store,objsize,1,pcofile) ; /* P-codeオブジェクトを読む*/
  1170.      objsize /= sizeof(_store) ;
  1171.  
  1172.      if(infor) {
  1173.       fprintf(stderr,"\n * Program name = %s\n",progname) ;
  1174.       fprintf(stderr," * Total memory = %5d words\n",Maxstore) ;
  1175.       fprintf(stderr," * Object size  = %5d words\n",objsize)  ;
  1176.       fprintf(stderr," * stack/heap   = %5d words\n\n",Maxstore-objsize) ;
  1177.      }
  1178.  
  1179.      if(fileno>2) inputfilename() ;
  1180.  
  1181.      signal(SIGINT,cntl_c) ;            /* CTRL-Cシグナル登録        */
  1182.      signal(SIGFPE,real_err) ;          /* 実数演算シグナル登録      */
  1183. }
  1184.  
  1185. /*******************************************/
  1186. /*  pitpr() : P-codeインタプリタメイン処理 */
  1187. /*******************************************/
  1188. void main(int argc,char **argv)
  1189. {
  1190.   register _store *adrinst ;
  1191.   int i ;
  1192.  
  1193.      init(argc,argv) ;
  1194.  
  1195.      pc = 0          ;
  1196.      mp = objsize    ;
  1197.      np = Maxstore   ;
  1198.      ep = objsize+5  ;
  1199.      sp = store+objsize-1  ;       /* スタックポインタの初期設定 */
  1200.  
  1201.  
  1202.      for(i=0;i<fileno;i++) {
  1203.       fi[i].fileadr += objsize ;        /* ファイルアドレスの修正     */
  1204.       fi[i].filebuf =  store + fi[i].fileadr ; /* バッファ変数アドレス*/
  1205.      }
  1206.  
  1207. loop :
  1208.       adrinst = store + pc++ ;
  1209.       p  = (*adrinst).vo.cdp  ;
  1210.       q  = (*adrinst).vo.cdq  ;
  1211.  
  1212.       if(trace)                         /* トレースオプション有効     */
  1213.        printf("%4d[%3d %1d %6d] mp=%4d np=%4d ep=%4d stack[%4d]=%08lxH\n",
  1214.          pc-1,(*adrinst).vo.cdop,p,q, mp,np,ep,sp-store,(*sp).vi);
  1215.  
  1216.       pcd[(*adrinst).vo.cdop].func() ;  /* opに対応した命令を実行     */
  1217.  
  1218.      goto loop;
  1219. }
  1220.